package comet.extract;

import java.util.ArrayList;
import java.util.Vector;

import comet.measure.GoogleDistanceCtrl;
import comet.measure.OntologyIntraDistance;
import comet.util.OntologyHelper;

import com.hp.hpl.jena.ontology.ObjectProperty;
import com.hp.hpl.jena.ontology.OntClass;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntProperty;

public class Modularizer {

	OntModel sourceOntology=null;
	String[] conceptLabels=null;
	double threshold =1.0;
	
	Vector<OntClass> relevantClasses=null;
	OntModel module=null;
	
	public Modularizer(OntModel webOntology, String[] terms, double threshold) {
		sourceOntology =webOntology;
		conceptLabels=terms;
		this.threshold = threshold;
	}
	
	public void modularize(){
		setInitialRelevantClasses();
		computeNewRelevantClassesAmongNeighborsOfInitialClasses();
		generateModule();
	}

	private void setInitialRelevantClasses() {
		relevantClasses = new Vector<OntClass>();
		for(int i=0;i<conceptLabels.length;i++)
			relevantClasses.add(OntologyHelper.geConcept(sourceOntology,conceptLabels[i]));
	// dont forget to add class ideals
	}

	private void computeNewRelevantClassesAmongNeighborsOfInitialClasses() {
		for(int i=0;i<relevantClasses.size();i++) {
			OntClass oc = relevantClasses.elementAt(i);
			computeNewRelevantClassesAmongNeighbors(oc);
		}
		
	}
	
	private void computeNewRelevantClassesAmongNeighbors(OntClass domainConcept) {
		ArrayList<OntProperty> relations = OntologyHelper.getOutgoingObjectProperties(domainConcept);
		for(int j=0;j<relations.size();j++) {
			ObjectProperty op = (ObjectProperty) relations.get(j);
			OntClass rangeConcept = (OntClass)op.getRange();
			double semanticDistance = getDistance(domainConcept,rangeConcept);
			if(semanticDistance>threshold) {
				if(relevantClasses.contains(rangeConcept)) continue;
				else  {
					relevantClasses.add(rangeConcept);
					// recursive call
					computeNewRelevantClassesAmongNeighbors(rangeConcept);
				}// else
			}//if distance 
		}//for
	}

	
	private double getDistance(OntClass domain, OntClass range) {
		double internalStructureBasedDistance = OntologyIntraDistance.getDistance(sourceOntology,domain,range);
		double externalRessourceBasedDistance= GoogleDistanceCtrl.getDistance(OntologyHelper.getClassLabel(domain),OntologyHelper.getClassLabel(range));
		return (2*internalStructureBasedDistance+externalRessourceBasedDistance)/3;
	}


	void generateModule() {
		// cutoff non relevant classes from the source ontology
	}
	
	OntModel getModule(OntModel sourceOntology, String[] terms) {
		return module;
	}
}
